package server.controller.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.web.bind.annotation.*;
import plug.result.ReqPage;
import plug.result.RetResponse;
import plug.result.RetResult;
import server.dao.*;
import server.model.dto.TransDto;
import server.model.dto.UserDepositDto;
import server.model.dto.UserDto;
import server.model.dto.UserSiteDto;
import server.model.entity.*;
import server.service.UserBlanceService;
import server.tool.tool.BeanUtil;
import server.tool.tool.EDcrypionUtils;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;

/**
 * 创建人:    xvzhe
 * 创建时间:
 * 修改时间:
 * 版本:      v1.0
 */
@RestController
@RequestMapping("v2/api/user")
@Api(value = "对外接口（用户信息）", tags = {"需登录(用户信息)"})
@CrossOrigin(origins = "*")
public class UsersController {
    @Autowired
    UserBlanceDao userBlanceDao;
    @Autowired
    UserSiteDao userSiteDao;
    @Autowired
    UserDepositDao userDepositDao;
    @Autowired
    UsersDao usersDao;
    @Autowired
    SignDao signDao;
    @Autowired
    UserBlanceService userBlanceService;
    @Autowired
    BlanceRecordDao blanceRecordDao;
    @Autowired
    FrmDictionDao frmDictionDao;
    @Autowired
    ApplyDao applyDao;
    @Autowired
    ShopOrderDao shopOrderDao;

    @PostMapping("/sign")
    @ApiOperation("签到")
    public RetResult sign() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        if (Optional.ofNullable(signDao.findTime(format, users.getId())).isPresent()) {
            return RetResponse.makeErrRsp("您已经签到过了！");
        }
        String yData = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
        int dayNum = 0;
        Sign dy = signDao.findTime(yData, users.getId());
        if (Optional.ofNullable(dy).isPresent()) {
            dayNum = dy.getDayNum() + 1;
        } else {
            dayNum = 1;
        }
        Sign sign = new Sign();
        sign.setUserId(users.getId());
        sign.setDayNum(dayNum);
        signDao.save(sign);
        userBlanceService.insBlance(users.getId(), new BigDecimal(dayNum), UserBlance.Type.TOTAL, BlanceRecord.Type.TOTAL_INS);
        return RetResponse.makeOKRsp();
    }

    @GetMapping("/sign")
    @ApiOperation("我的最近七天签到")
    public RetResult mySign() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        String yData = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
        Sign dy = signDao.findTime(yData, users.getId());

        String data = DateUtil.format(new Date(), "yyyy-MM-dd");
        Sign dys = signDao.findTime(data, users.getId());
        List<Sign> us = Lists.newLinkedList();
        if (Optional.ofNullable(dy).isPresent()) {
            for (int i = dy.getDayNum(); i >= dy.getDayNum() - 1; i--) {
                String ysData = DateUtil.format(DateUtil.offsetDay(new Date(), -1 * i), "yyyy-MM-dd");
                us.add(signDao.findTime(ysData, users.getId()));
            }
            if (dys != null) {
                us.add(dys);
            }
            return RetResponse.makeOKRsp(us);
        } else {
            if (dys != null) {
                us.add(dys);
            }
            return RetResponse.makeOKRsp(us);
        }
    }

    @PostMapping("/trans")
    @ApiOperation("转账")
    public RetResult trans(@RequestBody TransDto transDto) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        userBlanceService.trans(users.getId(), transDto);
        return RetResponse.makeOKRsp();
    }

    @ApiOperation("我的钱包")
    @GetMapping("/blance")
    public RetResult getBlance() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(userBlanceDao.findByUserId(users.getId()));
    }

    @ApiOperation("我的收货地址")
    @GetMapping("/site")
    public RetResult getSite() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(userSiteDao.findByUserIdAndStatus(users.getId(), true));
    }

    @ApiOperation("删除收货地址")
    @DeleteMapping("/site/{id}")
    public RetResult delSite(@PathVariable String id) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        Optional<UserSite> us = userSiteDao.findById(id);
        if (us.isPresent()) {
            if (us.get().getUserId().equals(users.getId())) {
                us.get().setStatus(false);
                userSiteDao.save(us.get());
                return RetResponse.makeOKRsp();
            } else {
                return RetResponse.makeErrRsp("error");
            }
        } else {
            return RetResponse.makeErrRsp("不存在的ID");
        }
    }

    @ApiOperation("删除提现地址")
    @DeleteMapping("/deposit/{id}")
    public RetResult deDepos(@PathVariable String id) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        Optional<UserDeposit> us = userDepositDao.findById(id);
        if (us.isPresent()) {
            if (us.get().getUserId().equals(users.getId())) {
                us.get().setStatus(false);
                userDepositDao.save(us.get());
                return RetResponse.makeOKRsp();
            } else {
                return RetResponse.makeErrRsp("error");
            }
        } else {
            return RetResponse.makeErrRsp("不存在的ID");
        }
    }

    @ApiOperation("我的提现方式")
    @GetMapping("/deposit")
    public RetResult getDeposit() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(userDepositDao.findByUserIdAndStatus(users.getId(), true));
    }

    @ApiOperation("新增提现方式")
    @PostMapping("/deposit")
    @Transactional
    public RetResult addDeposit(@RequestBody UserDepositDto userDepositDto) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        UserDeposit userDeposit = BeanUtil.convertToBean(userDepositDto, UserDeposit.class);
        userDeposit.setUserId(users.getId());
        userDeposit.setStatus(true);
        if (userDeposit.getType() == null) {
            userDeposit.setType(UserDeposit.Type.CARD);
        }
        if (userDeposit.getIsDefault()) {
            userDepositDao.updateDefaByUserId(users.getId());
        }
        userDeposit = userDepositDao.save(userDeposit);
        return RetResponse.makeOKRsp(userDeposit);
    }

    @ApiOperation("新增收货地址")
    @PostMapping("/site")
    @Transactional
    public RetResult addSite(@RequestBody UserSiteDto userSiteDto) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        UserSite userSite = BeanUtil.convertToBean(userSiteDto, UserSite.class);
        userSite.setUserId(users.getId());
        userSite.setStatus(true);
        userSite.setPick(false);
        if (userSite.getIsDefault()) {
            userSiteDao.updateDefaByUserId(users.getId());
        }
        userSite = userSiteDao.save(userSite);
        return RetResponse.makeOKRsp(userSite);
    }

    @PostMapping("/money")
    @ApiOperation("我的资金往来")
    public RetResult money(@RequestBody ReqPage reqPage) {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        JSONObject req = Optional.ofNullable(reqPage.getCommon()).orElseGet(JSONObject::new);
        BlanceRecord blanceRecord = JSON.parseObject(req.toJSONString(), BlanceRecord.class);
        blanceRecord.setStatus(true);
        blanceRecord.setUserId(users.getId());
        int page = reqPage.getPage() - 1;
        int size = reqPage.getLimit();
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "modifiedTime");
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("log", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<BlanceRecord> example = Example.of(blanceRecord, matcher);
        Page<BlanceRecord> pages = blanceRecordDao.findAll(example, pageable);
        return RetResponse.makeRsp(0, "成功", pages.getContent(), (int) pages.getTotalElements());
    }

    @GetMapping("/money/ins")
    @ApiOperation("我的奖励")
    public RetResult myMoney() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(blanceRecordDao.findByUserIdAndTO(users.getId()));
    }

    @GetMapping("/money/ins/collect")
    @ApiOperation("我的奖励统计")
    public RetResult myMoneyCollect() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        HashMap<String, Double> mp = Maps.newHashMap();
        //
        AtomicReference<Double> jl = new AtomicReference<>(0.0d);
        blanceRecordDao.findByUserIdAndTO(users.getId()).stream().forEach(item -> {
            jl.getAndSet(item.getAfter().subtract(item.getBefor()).doubleValue());
        });
        mp.put("ins", jl.get());
        double dp = applyDao.findByUserIdOrderByCreateTimeDesc(users.getId()).stream().mapToDouble(item -> item.getMoney().doubleValue()).sum();
        mp.put("tx", dp);
        List<String> ls = usersDao.findByTreeLike(users.getId()).stream().map(Users::getId).collect(Collectors.toList());
        mp.put("team", Double.valueOf(users.getPerformance()- users.getSelfPerformance()));
        return RetResponse.makeOKRsp(mp);
    }

    @GetMapping("/zp/trans")
    @ApiOperation("抽奖")
    public RetResult zpTrans() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        List<FrmDiction> zps = frmDictionDao.findByTypeOrderByKeyst("ZP").stream().filter(frmDiction -> Double.parseDouble(frmDiction.getVal4()) > 0).
                collect(Collectors.toList());
        Random rd = new Random();
        FrmDiction xp = zps.get(rd.nextInt(zps.size()));
        userBlanceService.insBlance(users.getId(), new BigDecimal(5), UserBlance.Type.TOTAL, BlanceRecord.Type.TOTAL_EEL);
        if (xp.getVal2().equals("1")) {

        } else if (xp.getVal2().equals("2")) {
            userBlanceService.insBlance(users.getId(), new BigDecimal(xp.getVal3()), UserBlance.Type.TOTAL, BlanceRecord.Type.TOTAL_III);
        } else if (xp.getVal2().equals("3")) {
            userBlanceService.insBlance(users.getId(), new BigDecimal(xp.getVal3()), UserBlance.Type.RMB, BlanceRecord.Type.TOTAL_III);
        }
        return RetResponse.makeOKRsp(xp);
    }

    @GetMapping("/performance")
    @ApiOperation("团队业绩")
    public RetResult performance() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        Map<String, Object> re = Maps.newHashMap();
        Map<String, Integer> mp = Maps.newHashMap();
        usersDao.findByParentId(users.getId()).stream().forEach(item -> {
            mp.put(item.getName(), item.getPerformance());
        });
        re.put("total", mp.values().stream().mapToInt(item -> item).sum());
        re.put("list", mp);
        return RetResponse.makeOKRsp(re);
    }

    @GetMapping("/inUser")
    @ApiOperation("是否可以邀请人")
    public RetResult inUser() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        return RetResponse.makeOKRsp(users.getActive());
    }

    @GetMapping("/plan")
    @ApiOperation("下一级进度条")
    public RetResult plan() {
        Users users = (Users) SecurityUtils.getSubject().getSession().getAttribute("Users");
        if (users.getGrade().equals(Users.Grade.GENERAL) || users.getGrade().equals(Users.Grade.VIP)) {
            return RetResponse.makeOKRsp(users.getPerformance()/20);
        }else if (users.getGrade().equals(Users.Grade.COLONEL)) {
            return RetResponse.makeOKRsp(users.getPerformance()/70);
        }else if (users.getGrade().equals(Users.Grade.MANAGER)) {
            return RetResponse.makeOKRsp(users.getPerformance()/300);
        }else if (users.getGrade().equals(Users.Grade.MAJOR)) {
            return RetResponse.makeOKRsp(users.getPerformance()/600);
        }else if (users.getGrade().equals(Users.Grade.TRUSTEE)) {
            return RetResponse.makeOKRsp(users.getPerformance()/1200);
        }else{
            return RetResponse.makeOKRsp(users.getPerformance()/2400);
        }
    }

    @PutMapping("/userInfo/{userId}")
    @ApiOperation("修改密码")
    public RetResult putsUser(@PathVariable String userId, @RequestParam String password,@RequestParam String oldPassword) {
        Users us = usersDao.findById(userId).get();
        if(!EDcrypionUtils.shiroPassword(oldPassword).equals(us.getPassword())){
            return RetResponse.makeErrRsp("旧密码不正确！");
        }
        us.setPassword(EDcrypionUtils.shiroPassword(password));
        try {
            usersDao.save(us);
        } catch (Exception e) {
            return RetResponse.makeErrRsp("失败");
        }
        return RetResponse.makeOKRsp();
    }
}
